﻿// 公司名称：松山湖材料实验室
// 项目名称：Micromach.Micromach.Common
// 文件名称：FileHelper.cs
// 创建日期：2019/04/11 12:57
// 功能描述：
// 作  者： 陈琦
// 最后修改：

using System;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading;

namespace RoboSensors.Tools
{
    public sealed class FileHelper
    {
        public static byte[] StreamToBytes(Stream stream)
        {
            try
            {
                byte[] array = new byte[stream.Length];
                stream.Read(array, 0, Convert.ToInt32(stream.Length));
                stream.Seek(0L, SeekOrigin.Begin);
                return array;
            }
            catch (IOException ex)
            {
                throw ex;
            }
            finally
            {
                stream.Close();
            }
        }

        public static Stream BytesToStream(byte[] bytes)
        {
            return new MemoryStream(bytes);
        }

        public static void BytesToFile(byte[] bytes, string fileName)
        {
            MemoryStream memoryStream = new MemoryStream(bytes);
            FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate);
            memoryStream.WriteTo(fileStream);
            memoryStream.Close();
            fileStream.Close();
        }

        public static Image BytesToImage(byte[] bytes)
        {
            MemoryStream memoryStream = new MemoryStream(bytes);
            memoryStream.Position = 0L;
            MemoryStream memoryStream2 = memoryStream;
            Image result = Image.FromStream(memoryStream2);
            memoryStream2.Close();
            return result;
        }

        public static byte[] ImageToBytes(Image image)
        {
            byte[] result = null;
            if (image != null)
            {
                lock (image)
                {
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        image.Save(memoryStream, ImageFormat.Png);
                        result = memoryStream.GetBuffer();
                    }
                }
            }
            return result;
        }

        public static byte[] ImageToBytes(Image image, ImageFormat imageFormat)
        {
            if (image != null)
            {
                byte[] array;
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (Bitmap bitmap = new Bitmap(image))
                    {
                        bitmap.Save(memoryStream, imageFormat);
                        memoryStream.Position = 0L;
                        array = new byte[memoryStream.Length];
                        memoryStream.Read(array, 0, Convert.ToInt32(memoryStream.Length));
                        memoryStream.Flush();
                    }
                }
                return array;
            }
            return null;
        }

        public static void StreamToFile(Stream stream, string fileName)
        {
            byte[] array = new byte[stream.Length];
            stream.Read(array, 0, array.Length);
            stream.Seek(0L, SeekOrigin.Begin);
            FileStream fileStream = new FileStream(fileName, FileMode.Create);
            BinaryWriter binaryWriter = new BinaryWriter(fileStream);
            binaryWriter.Write(array);
            binaryWriter.Close();
            fileStream.Close();
        }

        public static Stream FileToStream(string fileName)
        {
            FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            byte[] array = new byte[fileStream.Length];
            fileStream.Read(array, 0, array.Length);
            fileStream.Close();
            return new MemoryStream(array);
        }

        public static byte[] FileToBytes(string filePath)
        {
            int fileSize = GetFileSize(filePath);
            byte[] array = new byte[fileSize];
            FileInfo fileInfo = new FileInfo(filePath);
            FileStream fileStream = fileInfo.Open(FileMode.Open);
            try
            {
                fileStream.Read(array, 0, fileSize);
                return array;
            }
            catch (IOException ex)
            {
                throw ex;
            }
            finally
            {
                fileStream.Close();
            }
        }

        public static string FileToString(string filePath)
        {
            return FileToString(filePath, Encoding.Default);
        }

        public static string FileToString(string filePath, Encoding encoding)
        {
            try
            {
                using (StreamReader streamReader = new StreamReader(filePath, encoding))
                {
                    return streamReader.ReadToEnd();
                }
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }
        public static string FileToString1(string filePath)
        {
            try
            {
                return File.ReadAllText(filePath, Encoding.Default);
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }
        public static string ReadFileFromEmbedded(string fileWholeName)
        {
            string result;
            // ReSharper disable once AssignNullToNotNullAttribute
            using (
                TextReader textReader =
                    new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(fileWholeName)))
            {
                result = textReader.ReadToEnd();
            }
            return result;
        }

        public static Encoding GetEncoding(string filePath)
        {
            return GetEncoding(filePath, Encoding.Default);
        }

        public static Encoding GetEncoding(string filePath, Encoding defaultEncoding)
        {
            Encoding result = defaultEncoding;
            using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, 4))
            {
                if (fileStream.Length >= 2L)
                {
                    long position = fileStream.Position;
                    fileStream.Position = 0L;
                    int[] array = {
                        fileStream.ReadByte(),
                        fileStream.ReadByte(),
                        fileStream.ReadByte(),
                        fileStream.ReadByte()
                    };
                    fileStream.Position = position;
                    if (array[0] == 254 && array[1] == 255)
                    {
                        result = Encoding.BigEndianUnicode;
                    }
                    if (array[0] == 255 && array[1] == 254)
                    {
                        result = Encoding.Unicode;
                    }
                    if (array[0] == 239 && array[1] == 187 && array[2] == 191)
                    {
                        result = Encoding.UTF8;
                    }
                }
            }
            return result;
        }

        public static int GetFileSize(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            return (int)fileInfo.Length;
        }

        public static double GetFileSizeKB(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            return ConvertHelper.ToDouble(Convert.ToDouble(fileInfo.Length) / 1024.0, 1.0);
        }

        public static double GetFileSizeMB(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            return ConvertHelper.ToDouble(Convert.ToDouble(fileInfo.Length) / 1024.0 / 1024.0, 1.0);
        }

        public static void WriteText(string filePath, string content)
        {
            DirectoryHelper.CreateDirectory(Path.GetDirectoryName(filePath));
            File.WriteAllText(filePath, content, Encoding.Default);
        }

        public static void AppendText(string filePath, string content)
        {
            File.AppendAllText(filePath, content, Encoding.Default);
        }

        public static void Copy(string sourceFilePath, string destFilePath)
        {
            File.Copy(sourceFilePath, destFilePath, true);
        }

        public static void Move(string sourceFilePath, string descDirectoryPath)
        {
            ///string fileName = GetFileName(sourceFilePath);
            ////if (Directory.Exists(descDirectoryPath))
            //{
            //    if (IsExistFile(descDirectoryPath + "\\" + fileName))
            //    {
            //        DeleteFile(descDirectoryPath + "\\" + fileName);
            //    }
            //    File.Move(sourceFilePath, descDirectoryPath + "\\" + fileName);
            //}
            if (IsExistFile(descDirectoryPath))
            {
                DeleteFile(descDirectoryPath);
            }
            File.Move(sourceFilePath, descDirectoryPath);
        }

        public static bool IsExistFile(string filePath)
        {
            return File.Exists(filePath);
        }

        public static void CreateFile(string filePath)
        {
            try
            {
                if (!File.Exists(filePath))
                {
                    File.Create(filePath);
                }
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        public static void CreateFile(string filePath, byte[] buffer)
        {
            try
            {
                if (!File.Exists(filePath))
                {
                    using (FileStream fileStream = File.Create(filePath))
                    {
                        fileStream.Write(buffer, 0, buffer.Length);
                    }
                }
            }
            catch (IOException ex)
            {
                throw ex;
            }
        }

        public static int GetLineCount(string filePath)
        {
            string[] array = File.ReadAllLines(filePath);
            return array.Length;
        }

        public static string GetFileName(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            return fileInfo.Name;
        }

        public static string GetFileNameNoExtension(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            return fileInfo.Name.Substring(0, fileInfo.Name.LastIndexOf('.'));
        }

        public static string GetExtension(string filePath)
        {
            FileInfo fileInfo = new FileInfo(filePath);
            return fileInfo.Extension;
        }

        public static void ClearFile(string filePath)
        {
            File.Delete(filePath);
            CreateFile(filePath);
        }

        public static void DeleteFile(string filePath)
        {
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }
        }

        public static bool FileIsReadOnly(string fullpath)
        {
            FileInfo fileInfo = new FileInfo(fullpath);
            if ((fileInfo.Attributes & FileAttributes.ReadOnly) != FileAttributes.ReadOnly)
            {
                return false;
            }
            return true;
        }

        public static void SetFileReadonly(string fullpath, bool flag)
        {
            FileInfo fileInfo = new FileInfo(fullpath);
            if (flag)
            {
                fileInfo.Attributes |= FileAttributes.ReadOnly;
            }
            else
            {
                fileInfo.Attributes &= ~FileAttributes.ReadOnly;
            }
        }

        public static string GetFileName(string fullpath, bool removeExt)
        {
            FileInfo fileInfo = new FileInfo(fullpath);
            string text = fileInfo.Name;
            if (removeExt)
            {
                text = text.Remove(text.LastIndexOf('.'));
            }
            return text;
        }

        public static DateTime GetFileCreateTime(string fullpath)
        {
            FileInfo fileInfo = new FileInfo(fullpath);
            return fileInfo.CreationTime;
        }

        public static DateTime GetLastWriteTime(string fullpath)
        {
            FileInfo fileInfo = new FileInfo(fullpath);
            return fileInfo.LastWriteTime;
        }

        public static string CreateTempZeroByteFile()
        {
            return Path.GetTempFileName();
        }

        public static string GetRandomFileName()
        {
            return Path.GetRandomFileName();
        }

        public static bool CompareFilesHash(string fileName1, string fileName2)
        {
            using (HashAlgorithm hashAlgorithm = HashAlgorithm.Create())
            {
                using (FileStream inputStream = new FileStream(fileName1, FileMode.Open))
                {
                    using (FileStream inputStream2 = new FileStream(fileName2, FileMode.Open))
                    {
                        byte[] value = hashAlgorithm.ComputeHash(inputStream);
                        byte[] value2 = hashAlgorithm.ComputeHash(inputStream2);
                        return BitConverter.ToString(value) == BitConverter.ToString(value2);
                    }
                }
            }
        }



        public static void OpenFileInProcess(string fileName, byte[] bytes)
        {
            string tempFilePath = Path.Combine(DirectoryHelper.GetTempPath(), fileName);
            if (File.Exists(tempFilePath))
            {
                File.Delete(tempFilePath);
            }
            BytesToFile(bytes, tempFilePath);
            GetExtension(tempFilePath);
            GetFileName(tempFilePath);
            Thread thread = new Thread((ThreadStart)delegate
            {
                Process process = Process.Start(tempFilePath);
                if (process != null)
                {
                    process.WaitForExit();
                    if (File.Exists(tempFilePath))
                    {
                        File.Delete(tempFilePath);
                    }

                    process.Close();
                }
            });
            thread.Start();
        }

        #region 压缩、解压缩
        /// <summary>
        /// 压缩字节数组
        /// </summary>
        public static byte[] Compress(byte[] inputBytes)
        {
            using (MemoryStream outStream = new MemoryStream())
            {
                using (GZipStream zipStream = new GZipStream(outStream, CompressionMode.Compress, true))
                {
                    zipStream.Write(inputBytes, 0, inputBytes.Length);
                    zipStream.Close(); //很重要，必须关闭，否则无法正确解压
                    return outStream.ToArray();
                }
            }
        }

        /// <summary>
        /// 解压缩字节数组
        /// </summary>
        public static byte[] Decompress(byte[] inputBytes)
        {

            using (MemoryStream inputStream = new MemoryStream(inputBytes))
            {
                using (MemoryStream outStream = new MemoryStream())
                {
                    using (GZipStream zipStream = new GZipStream(inputStream, CompressionMode.Decompress))
                    {
                        zipStream.CopyTo(outStream);
                        zipStream.Close();
                        return outStream.ToArray();
                    }
                }

            }
        }

        /// <summary>
        /// 压缩字符串
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string Compress(string input)
        {
            if (input == null)
            {
                throw new Exception("转换失败！");
            }
            byte[] inputBytes = Encoding.Default.GetBytes(input);
            byte[] result = Compress(inputBytes);
            return Convert.ToBase64String(result);
        }
        /// <summary>
        /// 解压缩字符串
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string Decompress(string input)
        {
            byte[] inputBytes = Convert.FromBase64String(input);
            byte[] depressBytes = Decompress(inputBytes);
            return Encoding.Default.GetString(depressBytes);
        }
        #endregion
        public static void WriteFile(string fileName, string str)
        {
            DirectoryHelper.AssertDirExist(Path.GetDirectoryName(fileName));

            using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
            {
                using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8))
                {
                    sw.Write(str);
                    //sw.Write(Compress(str));
                    sw.Close();
                }
                fs.Close();
            }
        }
    }
}